// 对axios进行二次封装
// 1.指定基地址
// 2.请求拦截器-token
// 3.响应拦截器-bigint
import axios from 'axios';
// 在普通模块中获取veux中的数据,直接import
import store from '@/store/index.js';
import router from '@/router/index.js';
import JSONbig from 'json-bigint';

// 一个项目中的接口地址分别在多台不同的服务器上，即它们的基地址是不同的
const instance1 = axios.create({
  baseURL: 'http://ttapi.research.itcast.cn',
  // baseURL: 'http://api-toutiao-web.itheima.net',
  transformResponse: [function (data) {
    // console.log('transformResponse', data)
    // 响应数据转换
    // data就是本次请求获取的数据,进行大数处理
    // 后端返回的数据可能不是json字符串，而JSONbig.parse()只能处理json字符串,所以用try...catch...捕获异常
    try {
      return JSONbig.parse(data || '{}');
    } catch (error) {
      console.log('JSONbig转换出错', error);
      return data;
    }
  }]
});
// 在instance1上添加请求拦截器，补充请求头：token
instance1.interceptors.request.use(function (config) {
  // config当前请求的配置
  // 从vuex中取出token，添加在headers中
  const token = store.state.tokenInfo.token;
  if (token) {
    // 如果有就带上
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error);
});
// const instance2 = axios.create({
//   baseURL: 'http://ttapi.research.itcast.cn',
//   timeout: 1000
// });

// 响应拦截器
instance1.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  return response;
}, async function (error) {
  // 对响应错误做些什么
  // 401:token过期
  // 目的：用户对token无感知（免登陆 )
  if (error.response.status === 401) {
    console.log('error401');
    const refreshToken = store.state.tokenInfo.refresh_token;
    if (refreshToken) {
      try {
        // 用refresh_token重发请求来再次取回有效期为两小时的token
        // 特殊的接口，刷新用户token
        // 不要用instance1发请求，因为instance1的token废的，直接axios发请求
        const result = await axios({
          method: 'PUT',
          url: 'http://ttapi.research.itcast.cn/app/v1_0/authorizations',
          headers: {
            Authorization: `Bearer ${refreshToken}`
          }
        });
        console.log('refreshToken重新请求', result);
        const newToken = result.data.data.token;
        // 现在不在某个组件中，格式不是this.$store.commit
        // 就直接是store.commit('mutations名',新值)
        store.commit('mUpdateToken', newToken);

        // 重新发请求
        // instance1是创建的axios实例
        // error.config是前面得到的401错误的请求配置
        return instance1(error.config);
      } catch (error) {
        // 使用refresh_token获取新token失败
        console.log('使用refresh_token获取新token失败');
        // 回到登录页
        // 直接去登录
        // router是封装的路由对象，这里不是某个vue组件使用，不需要this.$router.push()
        router.push({
          path: '/login',
          query: {
            // currentRoute 当前路由对象
            backto: router.currentRoute.fullPath
          }
        });
      }
    } else {
      // 直接去登录
      router.push({
        path: '/login',
        query: {
          // currentRoute 当前路由对象
          backto: router.currentRoute.fullPath
        }
      });
    }
  } else {
    return Promise.reject(error);
  }
});

export default instance1; // 导入import ajax from './request.js'
// export {instance1, instance2}; // 导入import {instance1, instance2} from './request.js'
